#include "../math/quaternion.h"
#include "loop.h"

using namespace PBVP;

Loop::Loop(const std::vector<Vector3>& guide_points, double r)
{
	backbone_points = guide_points;
	radius = r;
	sides = 8;
	m_pGeoObject = NULL;
}

Loop::~Loop()
{
}

void Loop::render()
{
	// TODO
}

//////////////////////////////////////////////////////////////////////////
// private functions
//////////////////////////////////////////////////////////////////////////
void Loop::constructGeometry()
{
	if(m_pGeoObject) {
		// Geometry has already been constructed
		return;
	}
	// need to change this to interpolated points later
	points = backbone_points;
	int np = points.size();
	if (np < 2) {	// not enough points
		return;
	}
	// compute direction at each point
	std::vector<Vector3> directs;
	Vector3 dir, last;
	for (int i = 0; i < np; i++) {
        if (i != np-1) {
			dir = points[i+1]-points[i];
		} else {
			dir = points[i] - points[i-1];
		}
		dir.normalize();
		if(i == 0 || i == np-1) {	// the first or last point
			directs.push_back(dir);
		} else {
			// direction of intermediate points is the average of two sides
			Vector3 avg = (dir + last);
            avg.normalize();
			directs.push_back(avg);
		}
		last = dir;
	}

	m_pGeoObject = new GeometryData();
	// add the first point
	m_pGeoObject->addVertex(points[0], -directs[0]);
	// The extrusion points at the first point
	// First, find a vector perpendicular to the direction
	Vector3 norm = directs[0].perpendicular();
	for (int i = 0; i < sides; i++) {
        float angle = 2 * i * Math::PI / sides;
		Quaternion quat(angle, directs[0]);
		Vector3 rot_norm = quat * norm;
		Vector3 pnt = points[0] + rot_norm;
		m_pGeoObject->addVertex(pnt, rot_norm);
	}

	// Now extend those points to the disk at the next point
	
}
